package gbench.sandbox.plot.geom;

import gbench.common.matlib.MatlibCanvas;
import gbench.common.matlib.MatlibCanvas.NVec;
import gbench.common.matlib.img.ImageWrapper;
import org.junit.jupiter.api.Test;

import java.text.NumberFormat;
import java.util.function.Function;

import static gbench.common.matlib.MatlibCanvas.Range.NP2;
import static gbench.common.matlib.MatlibCanvas.Range.P2;
import static gbench.common.matlib.MatlibCanvas.Range.rg;
import static gbench.common.matlib.data.Pipe.DUMMY;
import static java.lang.Math.*;

/**
 * 绘制三角函数
 * @author gbench
 *
 */
public class JunitTrigonometric {
    
    /**
     * 绘制三角函数曲线
     */
    @Test
    public void plot() {
        final var size = 1000; // 绘图曲线
        final var matlib = new MatlibCanvas(size); // 绘图画布
        final var nf = NumberFormat.getInstance(); // 数字格式化器
        final var af = NVec.of(100, 100, size / 2, size / 4);// 仿射变换的参数
        final var fx = DUMMY((Function<Double,Number>)null).bind(f->NP2(2*PI, 1000).map(matlib.fx(f)).map(e -> e.affine(af))); // 函数图像绘制器
        
        matlib.plot(size, size / 2, pen -> { // 曲线的绘制
            //常用三角函数
            pen.setColor("#ff0000").drawLine(fx.eval(Math::sin)); // 正弦曲线 插值绘制 以连续化
            pen.setColor("#ffff00").drawLine(fx.eval(Math::cos)); // 余弦曲线 插值绘制 以连续化
            pen.setColor("#ff00ff").drawLine(fx.eval(Math::tan)); // 正切曲线 插值绘制 以连续化
            pen.setColor("#ff00ff").drawPoints(fx.eval(x->1/tan(x))); // 余切曲线
            pen.setColor("#aaaaaa").drawLine(P2(-PI,PI,100).map(matlib.rhotheta_affine(af))); // 补充一个单位元
            // 绘制几个参考的初等函数
            pen.setColor("#008800").drawPoints(fx.eval(Math::exp)); // 指数曲线
            pen.setColor("#008888").drawPoints(fx.eval(Math::log)); // 对数曲线
            pen.setColor("#880088").drawPoints(fx.eval(x->x*x*x)); // 3次幂曲线
            pen.setColor("#000088").drawPoints(fx.eval(x->x*x)); // 2次幂曲线
            pen.setColor("#aaaaaa").drawPoints(fx.eval(x->x)); // 正对角线曲线
            pen.setColor("#aaaaaa").drawPoints(fx.eval(x->-x)); // 负对角线曲线
        }, null, true, img -> { // 坐标轴的绘制
            final var g = new ImageWrapper(img, true).HL(rg(0, size), af.get(3)).VL(rg(0, size / 2), af.get(2)); // 绘制水平线
            NP2(2*PI, 20).forEach(x -> g.drawString(nf.format(x), x, 0, NVec.of(100, 1, af.get(2) + 4, af.get(3) - 14))); // x 轴刻度
            NP2(3, 20).forEach(y -> g.drawString(nf.format(y), 0, y, NVec.of(1, 100, af.get(2) + 4, af.get(3)))); // y 轴刻度
        });// plot
    }
    
    /**
     * 绘制三角函数曲线
     * @param args
     */
    public static void main(String args[]) {
        new JunitTrigonometric().plot();
    }

}
